﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Noris.Tools.TraceVisualiser.BlockingVisualiser.Data;
using Noris.Tools.TraceVisualiser.TraceData;
using Noris.Tools.TraceVisualiser.Support;

namespace Noris.Tools.TraceVisualiser.BlockingVisualiser.Forms
{
    public partial class LockForm : Noris.Tools.TraceVisualiser.Components.DForm
    {
        #region Konstrukce, layout, privátní eventhandlery
        public LockForm()
        {
            InitializeComponent();
			InitData();
        }
        private bool _FirstArrangeDone = false;
        private SqlLockConfig Config;
		protected void InitData()
		{
            this.KeyPreview = true;
            this.KeyDown += new KeyEventHandler(LockForm_KeyDown);
            this._ToolPrevBtn.Image = Pics.PicLibrary22.ArrowLeft2_FromFile;
            this._ToolNextBtn.Image = Pics.PicLibrary22.ArrowRight2_FromFile;
            this._LockPanel.ContentSizeChanged += new EventHandler(_LockPanel_ContentSizeChanged);
			this.Config = (SqlLockConfig)Steward.GetFromCache(typeof(SqlLockConfig));
			this._ToolShowProcessPoor.Checked = this.Config.ShowProcessWithoutOwning;
            this._ToolShowExchange.Checked = this.Config.ShowExchange;
			// this._ToolShowPipe.Checked = this.Config.ShowPipe;
            // this._ToolShowProcessPort.Checked = this.Config.ShowPort;
            this._LockPanel.Config = this.Config;
			this._ShowStatusInfo();
		}
        void LockForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.PageDown)
            {
                this.FindOtherEvent(this, new LockFormEventArgs(NextEventSide.Next));
                e.Handled = true;
            }
            else if (e.Control && e.KeyCode == Keys.PageUp)
            {
                this.FindOtherEvent(this, new LockFormEventArgs(NextEventSide.Previous));
                e.Handled = true;
            }
            if (e.Modifiers == Keys.None && e.KeyCode == Keys.Escape)
            {
                this.Close();
                e.Handled = true;
            }
        }
        private void _LockPanel_ContentSizeChanged(object sender, EventArgs e)
        {
            this.ArrangeBounds();
        }
        private void ArrangeBounds()
        {
            Size overSize = new System.Drawing.Size(this.Width - this._LockPanel.Width, this.Height - this._LockPanel.Height);
            Size contentSize = this._LockPanel.ContentSize;

            Form mainForm = Steward.MainForm;
            Rectangle area = (mainForm != null ? mainForm.Bounds : SystemInformation.WorkingArea);

            Size formSize = new System.Drawing.Size(contentSize.Width + overSize.Width, contentSize.Height + overSize.Height);
            if (formSize.Height > area.Height) formSize.Height = area.Height;
            int minWidth = formSize.Height * 2 / 3;
            if (formSize.Width < minWidth) formSize.Width = minWidth;
            if (formSize.Width > area.Width) formSize.Width = area.Width;

            // Pokud je toto okno již jednou zobrazeno, pak tato metoda smí obsah jen zvětšovat, ale ne zmenšovat:
            if (this._FirstArrangeDone)
            {
                if (formSize.Width <= this.Width && formSize.Height <= this.Height)
                    return;
            }

            if (formSize.Width == area.Width || formSize.Height == area.Height)
                this.WindowState = FormWindowState.Maximized;
            else
            {
                if (this.WindowState == FormWindowState.Maximized)
                    this.WindowState = FormWindowState.Normal;
                Point origin = new Point((area.Width - formSize.Width) / 2, (area.Height - formSize.Height) / 2);
                this.Bounds = new Rectangle(origin, formSize);
            }
            this._FirstArrangeDone = true;
        }
        private void _ToolShow_Click(object sender, EventArgs e)
        {
            this.Config.ShowProcessWithoutOwning = this._ToolShowProcessPoor.Checked;
            this.Config.ShowExchange = this._ToolShowExchange.Checked;
            // this.Config.ShowPipe = this._ToolShowPipe.Checked;
            // this.Config.ShowPort = this._ToolShowProcessPort.Checked;
            this.Config.Save();
            this._LockPanel.Config = this.Config;
            this._ShowStatusInfo();
        }
        private void _ToolPrevBtn_Click(object sender, EventArgs e)
        {
            if (this.FindOtherEvent != null)
                this.FindOtherEvent(this, new LockFormEventArgs(NextEventSide.Previous));
        }
        private void _ToolNextBtn_Click(object sender, EventArgs e)
        {
            if (this.FindOtherEvent != null)
                this.FindOtherEvent(this, new LockFormEventArgs(NextEventSide.Next));
        }
        private void _ToolClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void _ShowStatusInfo()
        {
            this._StatusProcessLbl.Text = "Procesy: " + this._LockPanel.SummarySpid;
            this._StatusResourceLbl.Text = "Zdroje: " + this._LockPanel.SummaryResource;
        }
        #endregion
        #region Public metody, eventy
        /// <summary>
        /// Zajistí promítnutí dat o deadlocku do grafu
        /// </summary>
        /// <param name="eventInfo"></param>
        /// <param name="xmlTextData"></param>
        /// <param name="deadlockTime"></param>
        public void ShowDeadlockLockInfoFromXml(EventInfo eventInfo, string xmlTextData, DateTime? deadlockTime)
        {
            SqlLockData lockData = SqlLockData.CreateFromXml(eventInfo, xmlTextData, deadlockTime);
            this._LockPanel.LockData = lockData;
			this._ShowStatusInfo();
		}
        /// <summary>
        /// Event, kterým si uživatel říká o zobrazení další události
        /// </summary>
        public event LockFormChangeHandler FindOtherEvent;
        #endregion
    }
    #region delegát LockFormChangeHandler, class LockFormEventArgs, enum NextEventSide - pro nalezení sousedního deadlocku
    public delegate void LockFormChangeHandler(object sender, LockFormEventArgs args);
    public class LockFormEventArgs : EventArgs
    {
        public LockFormEventArgs(NextEventSide nextEvent)
        {
            this.NextEvent = nextEvent;
        }
        /// <summary>
        /// Požadovaná strana
        /// </summary>
        public NextEventSide NextEvent { get; private set; }
    }
    /// <summary>
    /// Požadovaná strana
    /// </summary>
    public enum NextEventSide
    {
        None = 0,
        Previous,
        Next
    }
    #endregion
}
